"use strict";

var A = window.A || (window.A = {}),
    AModule = angular.module('a.core', [
        'ui.router',
        'oc.lazyLoad'
    ]);

function throwError(msg) {
    throw new Error(msg);
}

/**
 * 检测成员名是否规范
 */
function ensureSafeMemberName(name) {
    if (name === "__defineGetter__" || name === "__defineSetter__"
        || name === "__lookupGetter__" || name === "__lookupSetter__"
        || name === "__proto__") {
        throwError('[' + name + '] not a safe member name');
    }
    return name;
}

/**
 * 检测obj是否可使用
 */
function ensureSafeObject(obj) {
    if (!obj) {
        return obj;
    }
    // nifty check if obj is Function that is fast and works across iframes and other contexts
    var err = '';
    if (obj.constructor === obj) {
        err = 'Function';
    } else if (obj.window === obj) {// isWindow(obj)
        err = 'the Window';
    } else if (obj.children && (obj.nodeName || (obj.prop && obj.attr && obj.find))) {// isElement(obj)
        err = 'DOM nodes';
    } else if (obj === Object) {// block Object so that we can't get hold of dangerous Object.* methods
        err = 'Object';
    }
    if (err) {
        throwError('Referencing ' + err + ' expressions is disallowed!');
    }
    return obj;
}

angular.extend(A, {
    /**
     * 创建命名空间
     */
    ns: function (className, data, createdFn) {
        if (angular.isFunction(data)) {
            createdFn = data;
            data = {};
        }
        var cns = className.split('.'), o = window;
        if (cns.length) {
            for (var i = 0; i < cns.length; i++) {
                var cn = cns[i];
                ensureSafeMemberName(cn);
                o[cn] = o[cn] || {};
                o = o[cn];
                ensureSafeObject(o);
            }
        }
        angular.merge(o, data); // 深度复制
        if (createdFn) {
            if (createdFn === true && angular.isFunction(o.init)) {
                A.init(o);
            } else if (angular.isFunction(createdFn)) {
                createdFn.call(o);
            }
        }
    },
    /**
     * 初始化一个对象,并执行对象的 init 方法
     */
    init: function () {
        var o = arguments[0], argLength = arguments.length, args = [];
        if (argLength > 1) {
            args = Array.prototype.slice.apply(arguments, [1, argLength]);
        }
        // 不能在dom ready后才执行, 需要直接运行
        o.init.apply(o, args);
    }
});
